#pragma once
#include<iostream>
#include<string>
#include<vector>
#include"InetAddr.hpp"
#include"ThreadPool.hpp"
using task_t = std::function<void()>;
class MessageRoute
{
public:
    MessageRoute() 
    {

    }
    bool IsExist(const InetAddr& addr)
    {
        for(auto user: _online_user)
        {
            if(user == addr)
            {
                return true;
            }
        }
        return false;
    }
    void AddUser(const InetAddr &addr)
    {
        if(IsExist(addr)) return;
        _online_user.push_back(addr);
        std::cout<<"Add user success: " << addr.Ip() << ":" << addr.Port() << std::endl;
    }
    

    void DelUser(const InetAddr &user)
    {
        for(auto iter = _online_user.begin(); iter != _online_user.end(); ++iter)
        {
            if(*iter == user)
            {
                _online_user.erase(iter);
                std::cout<<"Del user success: " << user.Ip() << ":" << user.Port() << std::endl;
                break;
            }
        }
    }
    void RouteHelper(int sockfd,const std::string message)
    {
        for(auto user: _online_user)
        {
            // 转发工作:
            // 1.将消息转发给其他用户
            struct sockaddr_in addr = user.Sockaddr_in();
            ::sendto(sockfd,message.c_str(),message.size(),0,(struct sockaddr*)&addr,sizeof(user));
            std::cout<<"send message to user: " << user.Ip() << ":" << user.Port() << std::endl;
        }
    }

    // 进行消息转发
    void Route(int sockfd,const std::string message,const InetAddr who)
    {
        // 用户首次发消息,不仅仅是发消息,还需要将自己插入到在线用户中
        AddUser(who);

        
        if(message == "quit" || message == "q")
        {
            DelUser(who);
            std::cout<<"user quit: " << who.Ip() << ":" << who.Port() << std::endl;
        }

        // 构建任务对象,入队列,让线程转发
        task_t t = std::bind(&MessageRoute::RouteHelper,this,sockfd,message);
        ThreadPool<task_t>::GetInstance()->Enqueue(t);
        // 其他用户发消息
    }
    ~MessageRoute() 
    {

    }
private:
    std::vector<InetAddr> _online_user;
    // TODO
};